package com.cah.project.conf;

import org.aspectj.lang.annotation.Aspect;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
import org.springframework.transaction.interceptor.TransactionInterceptor;

import javax.annotation.Resource;

/**
 * 功能描述: 事物配置 <br/>
 */
@Aspect
@Configuration
public class TransactionConfig {

    private static final String AOP_POINTCUT_EXPRESSION = "execution (* com..service..*.*(..))";

    @Resource
    private TransactionManager transactionManager;

    public TransactionConfig() {

    }

    @Bean
    public TransactionInterceptor txAdvice() {
        // 有事物
        DefaultTransactionAttribute txAtt = new DefaultTransactionAttribute();
        txAtt.setPropagationBehavior(0);
        NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
        source.addTransactionalMethod("add*", txAtt);
        source.addTransactionalMethod("create*", txAtt);
        source.addTransactionalMethod("update*", txAtt);
        source.addTransactionalMethod("modify*", txAtt);
        source.addTransactionalMethod("save*", txAtt);
        source.addTransactionalMethod("delete*", txAtt);
        source.addTransactionalMethod("remove*", txAtt);
        source.addTransactionalMethod("del*", txAtt);
        source.addTransactionalMethod("do*", txAtt);
        source.addTransactionalMethod("copy*", txAtt);

        // 只读
        DefaultTransactionAttribute txAttRead = new DefaultTransactionAttribute();
        txAttRead.setPropagationBehavior(0);
        txAttRead.setReadOnly(true);
        source.addTransactionalMethod("get*", txAttRead);
        source.addTransactionalMethod("select*", txAttRead);
        source.addTransactionalMethod("find*", txAttRead);
        source.addTransactionalMethod("count*", txAttRead);
        source.addTransactionalMethod("query*", txAttRead);
        source.addTransactionalMethod("load*", txAttRead);
        source.addTransactionalMethod("reload*", txAttRead);

        return new TransactionInterceptor(this.transactionManager, source);
    }

    @Bean
    public Advisor txAdviceAdvisor() {
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
        return new DefaultPointcutAdvisor(pointcut, this.txAdvice());
    }

}
